#include "stdafx.h"
#include "GraphicFunctions.h"
#include "Settings.h"


#ifdef _DEBUG
#include "crtdbg.h"
#endif

inline COLOR16 GetGradientPoint(int s, int e, int y, int height)
{
  return (COLOR16)(s + ((e - s) * y) / height);
}

HFONT GraphicFunctions::BuildFont(const TCHAR* szFontName, int iFontSize, BOOL bBold, BOOL bItalic) {
  LOGFONT lf;
  memset(&lf, 0, sizeof(LOGFONT));

  lf.lfHeight = iFontSize;
  lf.lfWidth = 0;
  lf.lfEscapement = 0;
  lf.lfOrientation = 0;
  lf.lfWeight = bBold ? 600 : 500;
  lf.lfItalic = bItalic;
  lf.lfUnderline = false;
  lf.lfStrikeOut = false;
  lf.lfCharSet = EASTEUROPE_CHARSET;
  lf.lfOutPrecision = OUT_RASTER_PRECIS;
  lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
  if (Settings::useClearTypeFonts)
    lf.lfQuality = CLEARTYPE_QUALITY;
  else
    lf.lfQuality = NONANTIALIASED_QUALITY; 
  lf.lfPitchAndFamily = DEFAULT_PITCH | FF_DONTCARE;
  _tcsncpy (lf.lfFaceName, szFontName, LF_FACESIZE);
  return CreateFontIndirect(&lf);
}

void GraphicFunctions::DrawGradientGDI(HDC tdc, const RECT& iRect,
             COLORREF StartRGB, COLORREF EndRGB) {
           
  unsigned int Shift = 8;
  TRIVERTEX        vert[2] ;
  GRADIENT_RECT    gRect;
  vert [0] .x      = iRect.left;
  vert [0] .y      = iRect.top;
  vert [0] .Red    = GetRValue(StartRGB) << Shift;
  vert [0] .Green  = GetGValue(StartRGB) << Shift;
  vert [0] .Blue   = GetBValue(StartRGB) << Shift;
  vert [0] .Alpha  = 0x0000;
  vert [1] .x      = iRect.right;
  vert [1] .y      = iRect.bottom; 
  vert [1] .Red    = GetRValue(EndRGB) << Shift;
  vert [1] .Green  = GetGValue(EndRGB) << Shift;
  vert [1] .Blue   = GetBValue(EndRGB) << Shift;
  vert [1] .Alpha  = 0x0000;
  gRect.UpperLeft  = 0;
  gRect.LowerRight = 1;
  GradientFill(tdc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
}

void GraphicFunctions::DrawGradientGDI(HDC tdc, const RECT& iClip, const RECT& iRect,
             COLORREF StartRGB, COLORREF EndRGB)
{
  if (iRect.bottom == iRect.top)
    return;

  unsigned int Shift = 8;
  TRIVERTEX        vert[2] ;
  GRADIENT_RECT    gRect;
  vert [0] .x      = max(iClip.left, iRect.left);
  vert [0] .y      = max(iClip.top, iRect.top);
  if (vert [0] .y == iRect.top)
  {
    vert [0] .Red    = GetRValue(StartRGB) << Shift;
    vert [0] .Green  = GetGValue(StartRGB) << Shift;
    vert [0] .Blue   = GetBValue(StartRGB) << Shift;
  }
  else
  {
    int height = iRect.bottom - iRect.top;
    vert [0] .Red    = GetGradientPoint(GetRValue(StartRGB), GetRValue(EndRGB), iClip.top - iRect.top, height) << Shift;
    vert [0] .Green  = GetGradientPoint(GetGValue(StartRGB), GetGValue(EndRGB), iClip.top - iRect.top, height) << Shift;
    vert [0] .Blue   = GetGradientPoint(GetBValue(StartRGB), GetBValue(EndRGB), iClip.top - iRect.top, height) << Shift;
  }
  vert [0] .Alpha  = 0x0000;
  vert [1] .x      = min(iClip.right, iRect.right);
  vert [1] .y      = min(iClip.bottom, iRect.bottom); 
  if (vert [1] .y == iRect.bottom)
  {
    vert [1] .Red    = GetRValue(EndRGB) << Shift;
    vert [1] .Green  = GetGValue(EndRGB) << Shift;
    vert [1] .Blue   = GetBValue(EndRGB) << Shift;
  }
  else
  {
    int height = iRect.bottom - iRect.top;
    vert [1] .Red    = GetGradientPoint(GetRValue(StartRGB), GetRValue(EndRGB), iClip.bottom - iRect.top, height) << Shift;
    vert [1] .Green  = GetGradientPoint(GetGValue(StartRGB), GetGValue(EndRGB), iClip.bottom - iRect.top, height) << Shift;
    vert [1] .Blue   = GetGradientPoint(GetBValue(StartRGB), GetBValue(EndRGB), iClip.bottom - iRect.top, height) << Shift;
  }
  vert [1] .Alpha  = 0x0000;
  gRect.UpperLeft  = 0;
  gRect.LowerRight = 1;
  GradientFill(tdc, vert, 2, &gRect, 1, GRADIENT_FILL_RECT_V);
}

void GraphicFunctions::BltAlpha(HDC hdcDest, int nXOriginDest, int nYOriginDest,
              int nWidthDest, int nHeightDest,
              HDC hdcSrc, int nXOriginSrc, int nYoriginSrc,
              int nWidthSrc, int nHeightSrc,
              BYTE alpha) {

  // For WM2003
  //DWORD dRop = Alpha > 0 ? SRCAND : SRCCOPY;
  //BitBlt(hdcDest, Left, Top, Width, Height, hdcSrc, 0, 0, dRop);
  
  // For WM5.0
  BLENDFUNCTION bf;
  bf.BlendOp = AC_SRC_OVER;
  bf.BlendFlags = 0;
  bf.SourceConstantAlpha = alpha;
  bf.AlphaFormat = 0;
  AlphaBlend(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, 
    hdcSrc, nXOriginSrc, nYoriginSrc, nWidthSrc, nHeightSrc, bf);
}

COLORREF GraphicFunctions::GetMedianColor(COLORREF clr1, COLORREF clr2)
{
  return RGB(GetGradientPoint(GetRValue(clr1), GetRValue(clr2), 1, 2),
             GetGradientPoint(GetGValue(clr1), GetGValue(clr2), 1, 2),
             GetGradientPoint(GetBValue(clr1), GetBValue(clr2), 1, 2));
}
